package com.bodu.core.util;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信解密工具
 */
public class WechatUtil {

    private static final String SECRET_KEY_SPEC = "AES";

    private static final String CHIPHER = "AES/CBC/PKCS5Padding";


    /**
     * 微信登录的地址
     *
     * @param code
     * @return
     */
    public static String WX_GET_OPEN_ID_URL(String code, String appId, String appSecret) {
        return "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code";
    }

    /**
     * 得到 openId 和SessionKey 数据
     * @param jsCode
     * @return
     */
    public static Map<String, Object> getOpenId(String jsCode, String appId, String appSecret) {
        String url = WX_GET_OPEN_ID_URL(jsCode, appId, appSecret);
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            String responseBody = httpClient.execute(httpGet, httpResponse -> {
                int status = httpResponse.getStatusLine().getStatusCode();
                if (status < 200 || status >= 300) {
                    return null;
                }
                HttpEntity entity = httpResponse.getEntity();
                return entity != null ? EntityUtils.toString(entity) : null;
            });
            System.out.println(responseBody);
            if (responseBody != null) {
                return JSONObject.parseObject(responseBody);
            } else {
                return new HashMap<>();
            }
        } catch (IOException e) {
        }
        return new HashMap<>();
    }

    public static void main(String[] args) {
        String data = "L/ElCPQwM+N2rjn7fHz0WVZD/QrSecDCgmpF3J/C/yIi3PEte8TYtw3y9j5f9HKSOQS3AGt3qHD7KkKSDyLeEPlo+kR6zOZIKJD1jIC501vkVSq2CXci4aIzMWhIQufTz33cRusjXdvkWD0P3eOkne0LEKXP8C55gEhy9R2msB4pjX2edz9PL66e+brPqZHwba2VDZyLhEqXHmsvW/caj5qxh7AXVbdEDA+G3Asf7iMiqjytmZVETbHS2v794wDHoUnBG7lIx0Uh5ksoJGg56eoFS7pxx8r3WN99C/FEAxOqsBjsgiXUkAY1d9VtF4N5edvYJRV5Qm+7pUiROZ6T0vXmxvBO2L/qia1Ml80PfSEt5OW6JnufA+lDT7orMH+TXrpw18SYIVtNeonnBhZmQ9aukXRjfwPd3eJbKm1CoeCHcxeSdR198KfZ0Wfc5hdKISXT9oaLgi/cQ5rG3qzlrw==";
        String sessionKey = "w18pxInSPDMY704wiX4r6g==";
        String iv = "yOz8STsFSYkkZARFHjLf+w==";
       String res =  decrypt(sessionKey, iv, data);
        System.out.println(res);
    }

    /**
     * AES解密
     */
    public static String decrypt(String sessionKey,String encryptedIv,String encryptedData){
        // 转化为字节数组
        byte[] key = Base64.decode(sessionKey);
        byte[] iv = Base64.decode(encryptedIv);
        byte[] encData = Base64.decode(encryptedData);
        // 假如密钥缺乏16位，那么就补足
        int base =16;
        if (key.length % base !=0) {
            int groups = key.length / base +(key.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp,(byte) 0);
            System.arraycopy(key,0,temp,0,key.length);
            key = temp;
        }
        // 假如初始向量缺乏16位，也补足
        if (iv.length % base !=0) {
            int groups = iv.length / base +(iv.length % base != 0 ? 1 : 0);
            byte[] temp = new byte[groups * base];
            Arrays.fill(temp,(byte) 0);
            System.arraycopy(iv,0,temp,0,iv.length);
            iv = temp;
        }
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        String resultStr = null;
        try {
            Cipher cipher = Cipher.getInstance(CHIPHER);
            SecretKeySpec keySpec = new SecretKeySpec(key,SECRET_KEY_SPEC);
            cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);
            resultStr = new String(cipher.doFinal(encData),"UTF-8");
        } catch (Exception e){
            return null;
        }
        // 解析加密后的字符串
        return resultStr;
    }
}
